#include "gitlogpreviewwidget.h"
#include "ui_gitlogpreviewwidget.h"

#include <QDesktopWidget>
#include <QClipboard>
#include <QEvent>
#include <QPainter>
#include <QTableWidget>
#include <QTimer>

GitLogPreviewWidget::GitLogPreviewWidget(QWidget *parent) :
    QWidget(parent)
    , ui(new Ui::GitLogPreviewWidget)
    , m_instance(nullptr)
    , m_tableWidget(nullptr)
{
    ui->setupUi(this);

    setWindowFlags(Qt::ToolTip | Qt::FramelessWindowHint);
//    setAttribute(Qt::WA_ShowWithoutActivating);
//    setAttribute(Qt::WA_TranslucentBackground);

    m_process = new QProcess(this);
    connect(m_process, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished),
            this, &GitLogPreviewWidget::onGitProcessFinished);

    connect(ui->copyButton, &QPushButton::clicked, this, &GitLogPreviewWidget::onCopyHashClicked);

    setStyleSheet(R"(

    QPushButton {
        background-color: #3498db;
        border: none;
        border-radius: 3px;
        color: white;
        padding: 2px 8px;
        font-size: 8px;
    }
    QPushButton:hover {
        background-color: #2980b9;
    }

)");

}

GitLogPreviewWidget::~GitLogPreviewWidget()
{
    delete ui;
}

void GitLogPreviewWidget::setInstance(QTableWidget *newInstance)
{
    m_instance = newInstance;
    m_tableWidget = m_instance;
}

void GitLogPreviewWidget::setColumnsFunc(GetColumnsFunc newColumnsFunc)
{
    m_columnsFunc = newColumnsFunc;
}

void GitLogPreviewWidget::setDisplayContent(const QString &commitHash, const QString &author, const QString &date,
                                            const QString &message, const QString &changedFiles)
{
    ui->commitHashLabel->setText(QString("提交哈希: <b>%1</b>").arg(commitHash));
    ui->authorLabel->setText(QString("作者: %1").arg(author));
    ui->dateLabel->setText(QString("日期: %1").arg(date));
    ui->messageContent->setPlainText(message);
    ui->changesContent->setPlainText(changedFiles.isEmpty() ? "无文件变更" : changedFiles);

    ui->loadingLabel->hide();
    ui->contentFrame->show();
    ui->pathLabel->show();
}

void GitLogPreviewWidget::showAtPosition(const QPoint &pos, QTableWidgetItem *item)
{
    QPoint adjustedPos = pos;
    adjustDisplayPosition(adjustedPos);

    move(adjustedPos);
    show();
    raise();

    Columns columns = m_columnsFunc(item);
    ui->pathLabel->setText(QString("仓库路径: %1").arg(columns.realpath));

    // 未检出时
    if (!columns.checkeouted) {
        setDisplayContent("", "", "", "错误: 仓库未检出", " ");
        return;
    }

    // 工作位置相同
    if (m_process->workingDirectory() == columns.realpath) {
        return;
    }

    fetchGitLog(columns.realpath);

//    QProcess process;
//    process.setWorkingDirectory(columns.realpath);
//    process.start("git", {"log", "--pretty=format:%H|%an|%ad|%s", "--date=short", "-n", "1", "--name-status",/*"--pretty=raw"*/});
//    process.waitForFinished();
}

void GitLogPreviewWidget::fetchGitLog(const QString &workdir)
{
    if (m_process->state() == QProcess::Running) {
        m_process->kill();
    }

    ui->loadingLabel->show();
    m_process->setWorkingDirectory(workdir);
    m_process->start("git",{"log", "--pretty=format:%H|%an|%ad|%s", "--date=short", "-n", "1", "--name-status",/*"--pretty=raw"*/});
}

void GitLogPreviewWidget::onGitProcessFinished(int exitCode, QProcess::ExitStatus exitStatus)
{
    if (exitStatus == QProcess::NormalExit && exitCode == 0) {
        QByteArray output = m_process->readAllStandardOutput();
        if (output.isEmpty()) {
            setDisplayContent("", "", "", "暂无提交记录", "");
        } else {
            QString logText = QString::fromLocal8Bit(output).trimmed();
            parserOutput(logText);
        }
    } else {
        QByteArray errorOutput = m_process->readAllStandardError();
        QString errorText = QString::fromLocal8Bit(errorOutput).trimmed();
        setDisplayContent("", "", "", "错误: " + (errorText.isEmpty() ? "无法获取 Git 日志" : errorText), "");
    }
}

void GitLogPreviewWidget::onCopyHashClicked()
{
    QString hash = ui->commitHashLabel->text();
    if (hash.contains(':')) {
        hash = hash.section(':', 1).remove("<b>").remove("</b>").trimmed().left(8);
        QApplication::clipboard()->setText(hash);

        // 提供反馈
        ui->copyButton->setText("已复制");
        QTimer::singleShot(1000, this, [this]() {
            ui->copyButton->setText("复制哈希");
        });
    }
}

void GitLogPreviewWidget::parserOutput(const QString &output)
{
    QStringList lines = output.split('\n', Qt::SkipEmptyParts);
    if (lines.isEmpty()) {
        setDisplayContent("","","", "暂无提交记录", "");
        return;
    }
/**
$ git log '--pretty=format:%H|%an|%ad|%s' --date=short -n 1 --name-status
45d30d07ad284018481ebb419b5d01b5de72ed02|Steve Muckle|2020-07-22|remove prebuilt ramdisk
D       arm64/gki-ramdisk.cpio
*/
    // 解析第一行：提交信息
    QStringList commitparts = lines[0].split("|");
    if (commitparts.size() >= 4) {
        QString commitHash = commitparts[0].left(24) + "...";
        QString author = commitparts[1];
        QString date = commitparts[2];
        QString message = commitparts[3];

        QStringList changedFiles;
        for(int i = 1; i < lines.size() && i < 6; ++i) {
            if (!lines[i].trimmed().isEmpty()) {
                changedFiles << lines[i].trimmed();
            }
        }
        setDisplayContent(commitHash, author, date, message, changedFiles.join("\n"));
    } else {
        setDisplayContent("", "", "", "解析 Git 日志失败", "");
    }
}

void GitLogPreviewWidget::adjustDisplayPosition(QPoint &pos)
{
    QRect screenGeometry = QApplication::desktop()->availableGeometry(this);

    if (pos.x() + width() > screenGeometry.right()) {
        pos.setX(screenGeometry.right() - width() - 10);
    }
    if (pos.y() + height() > screenGeometry.bottom()) {
        pos.setY(screenGeometry.bottom() - height() - 10);
    }

    pos.setX(qMax(screenGeometry.left() + 10, pos.x()));
    pos.setY(qMax(screenGeometry.top() + 10, pos.y()));
}

bool GitLogPreviewWidget::eventFilter(QObject *watched, QEvent *event)
{
    if (m_instance) {
        if (watched == m_instance->viewport()) {
            if (event->type() == QEvent::ToolTip || (!isHidden() && event->type() == QEvent::HoverMove)) {
                QPoint globalPos = QCursor::pos();
                QPoint tablePos = m_tableWidget->viewport()->mapFromGlobal(globalPos);
                QTableWidgetItem *item = m_tableWidget->itemAt(tablePos);
                if (item) {
                    QPoint previewPos = globalPos + QPoint(15, 15);
                    showAtPosition(previewPos, item);
                }
            }
        }
    }
    return QWidget::eventFilter(watched, event);
}

void GitLogPreviewWidget::showEvent(QShowEvent *event)
{
    QWidget::showEvent(event);
}

void GitLogPreviewWidget::paintEvent(QPaintEvent *event)
{
    QWidget::paintEvent(event);

    // 添加阴影效果
    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing);
}

void GitLogPreviewWidget::leaveEvent(QEvent *event)
{
    hide();
}

